home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolf3dmacsource.sit / Wolf3DMacSource / Sight.c < prev    next >
C/C++ Source or Header  |  1994-10-04  |  5KB  |  179 lines

  1. #include "wolfdef.h"
  2.  
  3. /**********************************
  4.  
  5.     Returns True if a straight line between the player and actor is unobstructed
  6.  
  7. **********************************/
  8.  
  9. Boolean CheckLine(actor_t *ActorPtr)
  10. {
  11.     Word actorx,actory,actortx,actorty;        /* Current actor's coords */
  12.     Word playerx,playery,playertx,playerty;    /* Player's coords */
  13.     Word xl,xh,yl,yh;                /* Min x,y Max x,y for test */
  14.     int delta;        /* Pixel differance to calc Step and Frac */
  15.     int Step;        /* Step value for each whole xy */
  16.     Word Frac;        /* Fractional xy stepper */
  17.     Word deltafrac;    /* True distance for whole numbers */
  18.     Word intercept;    /* Temp for door code */
  19.     Word tile;        /* Temp for tile check */
  20.     Byte partial;    /* Fraction to force whole numbers */
  21.     
  22.     actorx = ActorPtr->x;        /* Get the actor's x,y */
  23.     actortx = actorx>>FRACBITS;    /* Get the actor's tile x,y */
  24.     actory = ActorPtr->y;
  25.     actorty = actory>>FRACBITS;
  26.  
  27.     playerx = actors[0].x;    /* Get the player's x,y */
  28.     playertx = playerx>>FRACBITS;    /* Get the player's tile x,y */
  29.     playery = actors[0].y;    
  30.     playerty = playery>>FRACBITS;
  31.  
  32.     /* The actor COULD be standing on a blocked tile (On a CLOSING door tile) */
  33.  
  34. #if 0
  35.     if (tilemap[actorty][actortx] & TI_BLOCKSIGHT) {    /* Is the actor IN a wall? */
  36.         return FALSE;            /* This could happen on a closing door */
  37.     }
  38. #endif
  39.  
  40. /* check for solid tiles at x crossings */
  41.     
  42.     if (playertx!=actortx) {        /* Scan in the x direction? */
  43.         if (actortx<playertx) {        
  44.             partial = -actorx;    /* Isolate the fraction */
  45.             xl = actortx-1;            /* Actor is on the left side */
  46.             xh = playertx-1;
  47.             yl = actory;
  48.             yh = playery;
  49.             deltafrac = playerx-actorx;    /* Distance in pixels */
  50.         } else {
  51.             partial = -playerx;
  52.             xl = playertx;            /* Player is on the left side */
  53.             xh = actortx;
  54.             yl = playery;
  55.             yh = actory;
  56.             deltafrac = actorx-playerx;    /* Distance in pixels */
  57.         }
  58.         delta = yh-yl;                /* Y adjust (Signed) */
  59.         if (w_abs(delta) >= (16*FRACUNIT) || deltafrac >= (16*FRACUNIT)) {    /* Farther than 16 tiles? */
  60.             return FALSE;
  61.         }
  62.         Step = FixedDiv(delta,deltafrac);        /* How much to y step */
  63.         Frac = FixedByFrac(Step,partial)+yl;    /* Init the Y coord */
  64.         do {
  65.             ++xl;
  66.             tile = tilemap[Frac>>FRACBITS][xl];        /* Get the current tile */
  67.             if (tile & TI_BLOCKSIGHT) {
  68.                 return FALSE;        /* Can't see! */
  69.             }
  70.             if (tile & TI_DOOR) {    /* see if the door is open enough*/
  71.                 intercept = ((Step/2)+Frac)&0xff;
  72.                 if (intercept > doors[tile&TI_NUMMASK].position) {
  73.                     return FALSE;    /* Can't see! */
  74.                 }
  75.             }
  76.             Frac += Step;
  77.         } while (xl<xh);
  78.     }
  79.  
  80. /* check for solid tiles at y crossings */
  81.  
  82.     if (playerty!=actorty) {
  83.         if (actorty<playerty) {
  84.             partial = -actory;
  85.             xl = actorx;
  86.             xh = playerx;
  87.             yl = actorty-1;
  88.             yh = playerty-1;
  89.             deltafrac = playery-actory;
  90.         } else {
  91.             partial = -playery;
  92.             xl = playerx;
  93.             xh = actorx;
  94.             yl = playerty;
  95.             yh = actorty;
  96.             deltafrac = actory-playery;
  97.         }
  98.         delta = xh-xl;        /* Number of tiles to scan */
  99.         if (w_abs(delta) >= 16*FRACUNIT || deltafrac >= 16*FRACUNIT) {
  100.             return FALSE;
  101.         }
  102.         Step = FixedDiv(delta,deltafrac);
  103.         Frac = FixedByFrac(Step,partial)+xl;
  104.         do {
  105.             ++yl;    
  106.             tile = tilemap[yl][Frac>>FRACBITS];
  107.             if (tile & TI_BLOCKSIGHT) {
  108.                 return FALSE;
  109.             }
  110.             if (tile & TI_DOOR) {    /* see if the door is open enough*/
  111.                 intercept = ((Step/2)+Frac)&0xff;
  112.                 if (intercept > doors[tile&TI_NUMMASK].position) {
  113.                     return FALSE;    /* Can't see! */
  114.                 }
  115.             }
  116.             Frac += Step;
  117.         } while (yl<yh);
  118.     }
  119.     return TRUE;    /* You are visible */
  120. }
  121.  
  122. /**********************************
  123.  
  124.     Puts actor into attack mode, either after reaction time or being shot
  125.  
  126. **********************************/
  127.  
  128. void FirstSighting(actor_t *ActorPtr)
  129. {
  130.     classinfo_t    *info;
  131.     Word sound;
  132.     
  133.     info = &classinfo[ActorPtr->class];    /* Get pointer to info record */
  134.     sound = info->sightsound;            /* Get the requested sound */
  135.     if (sound == SND_ESEE) {    /* make random human sound*/
  136.         sound = NaziSound[w_rnd()&3];    /* Make a differant sound */
  137.     }
  138.     PlaySound(sound|0x8000);            /* Play the sight sound */
  139.     NewState(ActorPtr,info->sightstate);    /* Set the next state */
  140.     ActorPtr->flags |= FL_ACTIVE;            /* Make it active */
  141. }
  142.  
  143. /**********************************
  144.  
  145.     Called by actors that ARE NOT chasing the player. If the player
  146.      is detected (by sight, noise, or proximity), the actor is put into
  147.      it's combat frame.
  148.  
  149.      Incorporates a random reaction delay.
  150.  
  151. **********************************/
  152.  
  153. void T_Stand(actor_t *ActorPtr)
  154. {
  155.     if (ActorPtr->reacttime) {        /* Waiting to react? */
  156.         if (ActorPtr->reacttime>TicCount) {    /* Still waiting? */
  157.             ActorPtr->reacttime-=TicCount;    /* Count down */
  158.             return;
  159.         }
  160.         if (ActorPtr->flags&FL_AMBUSH ) {    /* Ambush actor? */
  161.             if (!CheckLine(ActorPtr)) {    /* Can I see you? */
  162.                 ActorPtr->reacttime=1;    /* be very ready, but*/
  163.                 return;                    /* don't attack yet*/
  164.             }
  165.             ActorPtr->flags &= ~FL_AMBUSH;    /* Clear the ambush flag */
  166.         }
  167.         FirstSighting(ActorPtr);        /* Attack the player! */
  168.         ActorPtr->reacttime=0;
  169.     }
  170.  
  171. /* Haven't seen player yet*/
  172.  
  173.     if (madenoise || CheckLine(ActorPtr)) {    /* Made a gun shot? Seen? */
  174.         ActorPtr->reacttime = (w_rnd() & classinfo[ActorPtr->class].reactionmask)*4+1;
  175.     }
  176. }
  177.  
  178.  
  179.